package com.example.businessmanage.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.api.client.UserClient;
import com.example.businessmanage.domain.dto.FosterUserRespDTO;
import com.example.businessmanage.domain.dto.LendApplyDTO;
import com.example.businessmanage.domain.dto.OwnerRetrieveDTO;
import com.example.businessmanage.domain.dto.SelectFosterDTO;
import com.example.businessmanage.domain.po.FosterIntentPO;
import com.example.businessmanage.domain.po.UserCreditPO;
import com.example.api.client.PetInfoFeignClient;
import com.example.businessmanage.mapper.FosterIntentMapper;
import com.example.businessmanage.mapper.UserCreditMapper;
import com.example.businessmanage.service.LendService;
import com.example.api.dto.PetInfoRespDTO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 暂时外借业务实现类
 */
@Service
@RequiredArgsConstructor
public class LendServiceImpl implements LendService {

    private final PetInfoFeignClient petInfoFeignClient;
    private final UserClient userFeignClient;
    private final FosterIntentMapper fosterIntentMapper;
    private final UserCreditMapper userCreditMapper;

    /**
     * 脱敏手机号（如138****1234）
     */
    private String desensitizePhone(String phone) {
        if (phone == null || phone.length() != 11) {
            return phone;
        }
        return phone.substring(0, 3) + "****" + phone.substring(7);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean applyLend(LendApplyDTO lendApplyDTO, Long ownerUserId) {
        // 1. 校验参数
        Long petId = lendApplyDTO.getPetId();
        Assert.notNull(petId, "宠物ID不能为空");
        Assert.notNull(ownerUserId, "主人用户ID不能为空");

        // 2. 远程调用pet-info-service，查询宠物信息（校验权限+当前状态）
        PetInfoRespDTO petInfo = petInfoFeignClient.getPetInfoById(petId);
        Assert.notNull(petInfo, "宠物不存在");
        Assert.isTrue(ownerUserId.equals(petInfo.getOwnerUserId()), "无权限操作该宠物");
        Assert.isTrue(petInfo.getLendStatusDesc().equals("不外借"), "当前宠物非“不外借”状态，无法发起外借申请");

        // 3. 远程调用更新宠物外借状态（0→1）
        return petInfoFeignClient.updateLendStatus(petId, 1, ownerUserId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean selectFoster(SelectFosterDTO selectFosterDTO, Long ownerUserId) {
        // 1. 校验参数
        Long petId = selectFosterDTO.getPetId();
        Long fosterUserId = selectFosterDTO.getFosterUserId();
        Assert.notNull(petId, "宠物ID不能为空");
        Assert.notNull(fosterUserId, "代养人ID不能为空");
        Assert.notNull(ownerUserId, "主人用户ID不能为空");

        // 2. 校验宠物归属+当前状态（必须是1-已申请外借或6-代养人申请返回）
        PetInfoRespDTO petInfo = petInfoFeignClient.getPetInfoById(petId);
        Assert.notNull(petInfo, "宠物不存在");
        Assert.isTrue(ownerUserId.equals(petInfo.getOwnerUserId()), "无权限操作该宠物");
        String currentStatus = petInfo.getLendStatusDesc();
        Assert.isTrue(currentStatus.equals("已申请外借") || currentStatus.equals("代养人申请返回"),
                "当前宠物状态不支持选择代养人（需为“已申请外借”或“代养人申请返回”）");

        // 3. 校验代养人是否在“待选择代养人集合”中
        FosterIntentPO intentPO = fosterIntentMapper.selectByFosterAndPet(fosterUserId, petId);
        Assert.notNull(intentPO, "该代养人未发送代养意向，无法选择");

        // 4. 远程调用更新宠物外借状态（1/6→2）+ 负责人ID（改为代养人ID）
        Boolean statusUpdate = petInfoFeignClient.updateLendStatus(petId, 2, fosterUserId);
        if (!statusUpdate) {
            return false;
        }

        // 5. （可选）初始化代养业务记录（foster_business表）
        // 此处需注入FosterBusinessMapper，简化代码暂不实现，实际项目需补充

        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean retrievePet(OwnerRetrieveDTO ownerRetrieveDTO, Long ownerUserId) {
        // 1. 校验参数
        Long petId = ownerRetrieveDTO.getPetId();
        Integer currentLendStatus = ownerRetrieveDTO.getCurrentLendStatus();
        Assert.notNull(petId, "宠物ID不能为空");
        Assert.notNull(currentLendStatus, "当前外借状态不能为空");
        Assert.notNull(ownerUserId, "主人用户ID不能为空");

        // 2. 校验宠物归属+状态一致性（前端传入状态需与后端一致）
        PetInfoRespDTO petInfo = petInfoFeignClient.getPetInfoById(petId);
        Assert.notNull(petInfo, "宠物不存在");
        Assert.isTrue(ownerUserId.equals(petInfo.getOwnerUserId()), "无权限操作该宠物");
        // 转换前端传入的数字状态为文本描述，校验一致性
        String statusDesc = getLendStatusDesc(currentLendStatus);
        Assert.isTrue(statusDesc.equals(petInfo.getLendStatusDesc()), "宠物状态已变更，请刷新页面后重试");

        // 3. 根据当前状态确定目标状态
        Integer targetStatus;
        if (currentLendStatus == 4) {
            // 当前状态4-在代养人手里→改为5-主人申请返回
            targetStatus = 5;
        } else if (currentLendStatus == 6) {
            // 当前状态6-代养人申请返回→改为7-返回中
            targetStatus = 7;
        } else {
            throw new IllegalArgumentException("当前状态（" + statusDesc + "）不支持申请取回");
        }

        // 4. 远程调用更新宠物外借状态
        return petInfoFeignClient.updateLendStatus(petId, targetStatus, ownerUserId);
    }

    @Override
    public IPage<FosterUserRespDTO> getToBeSelectedFoster(Long petId, Long ownerUserId, Integer pageNum, Integer pageSize) {
        // 1. 校验权限（必须是宠物主人）
        PetInfoRespDTO petInfo = petInfoFeignClient.getPetInfoById(petId);
        Assert.notNull(petInfo, "宠物不存在");
        Assert.isTrue(ownerUserId.equals(petInfo.getOwnerUserId()), "无权限查看该宠物的代养人列表");

        // 2. 分页查询代养意向（含代养人ID）
        Page<FosterIntentPO> page = new Page<>(pageNum, pageSize);
        IPage<FosterIntentPO> intentPage = fosterIntentMapper.selectFosterByPetId(page, petId);
        if (CollectionUtils.isEmpty(intentPage.getRecords())) {
            return new Page<>();
        }

        // 3. 批量获取代养人基础信息（昵称、联系方式）
        List<Long> fosterUserIds = intentPage.getRecords().stream()
                .map(FosterIntentPO::getFosterUserId)
                .distinct()
                .collect(Collectors.toList());
        String userIdsStr = StringUtils.collectionToCommaDelimitedString(fosterUserIds);
        Map<Long, Map<String, String>> userInfoMap = userFeignClient.batchGetUserBasicInfo(userIdsStr);

        // 4. 批量获取代养人信用分
        Map<Long, Integer> creditMap = fosterUserIds.stream()
                .collect(Collectors.toMap(
                        userId -> userId,
                        userId -> userCreditMapper.selectByUserIdWithDefault(userId).getCreditScore()
                ));

        // 5. 转换为DTO分页结果
        return intentPage.convert(intentPO -> {
            Long fosterUserId = intentPO.getFosterUserId();
            Map<String, String> userInfo = userInfoMap.getOrDefault(fosterUserId, Map.of());

            FosterUserRespDTO dto = new FosterUserRespDTO();
            dto.setFosterUserId(fosterUserId);
            dto.setFosterUserName(userInfo.getOrDefault("userName", "未知用户"));
            dto.setCreditScore(creditMap.getOrDefault(fosterUserId, 90));
            dto.setFosterPhone(desensitizePhone(userInfo.getOrDefault("phone", "")));
            dto.setIntentCreateTime(intentPO.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")));
            return dto;
        });
    }

    /**
     * 数字外借状态转文本描述（与pet-info-service一致）
     */
    private String getLendStatusDesc(Integer status) {
        switch (status) {
            case 0: return "不外借";
            case 1: return "已申请外借";
            case 2: return "已选择代养";
            case 3: return "运输中";
            case 4: return "在代养人手里";
            case 5: return "主人申请返回";
            case 6: return "代养人申请返回";
            case 7: return "返回中";
            default: return "未知状态";
        }
    }
}
